package com.instalinks.android.smspostservice.service;

import java.util.Hashtable;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.IBinder;

import com.instalinks.android.lib.UrlData;
import com.instalinks.android.smspostservice.receiver.CallReceiver;
import com.instalinks.android.smspostservice.receiver.SmsReceiver;
import com.instalinks.android.smspostservice.utils.AppConfig;
import com.instalinks.android.smspostservice.utils.AppNotifications;
import com.instalinks.android.smspostservice.utils.enums.ConfigParams;
import com.instalinks.android.smspostservice.utils.enums.PhoneParams;
import com.instalinks.android.smspostservice.utils.enums.ServiceStartStatus;
import com.instalinks.android.smspostservice.utils.enums.TimeOuts;

public class AppService extends Service {

	private BroadcastReceiver mSmsReceiver;
	private BroadcastReceiver mCallReceiver;
	private AppNotifications appNotifications;
	private AppConfig mAppConfig;

	private Handler demoRunHandler;
	private Handler configPullHandler;
	private Handler wakeupHandler;
	private Handler statsUpdateHandler;
	

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onCreate() {

		mAppConfig = new AppConfig(getApplicationContext());

		mSmsReceiver = new SmsReceiver();
		mCallReceiver = new CallReceiver();

		if (mAppConfig.isSmsServiceFlag()) {
			IntentFilter smsFilter = new IntentFilter(
			"android.provider.Telephony.SMS_RECEIVED");
			smsFilter.setPriority(999);
			this.registerReceiver(this.mSmsReceiver, smsFilter);
		}

		if (mAppConfig.isMissedServiceServiceFlag()) {
			IntentFilter callFilter = new IntentFilter(
			"android.intent.action.PHONE_STATE");
			callFilter.setPriority(999);
			this.registerReceiver(this.mCallReceiver, callFilter);
		}
		
		appNotifications = new AppNotifications(getApplicationContext());

		demoRunHandler = new Handler();
		demoRunHandler.removeCallbacks(demoRunTask);
		demoRunHandler.postAtTime(demoRunTask, TimeOuts.FiveSec.getValue());

		statsUpdateHandler = new Handler();
		statsUpdateHandler.removeCallbacks(statusUpdater);
		statsUpdateHandler.postAtTime(statusUpdater, TimeOuts.FiveSec.getValue());

		configPullHandler = new Handler();
		configPullHandler.removeCallbacks(configPullTask);
		configPullHandler.postAtTime(configPullTask, TimeOuts.SixHr.getValue());

		wakeupHandler = new Handler();
		wakeupHandler.removeCallbacks(wakeUp);
		wakeupHandler.postAtTime(wakeUp, TimeOuts.FiveSec.getValue());

	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		super.onStartCommand(intent, flags, startId);

		appNotifications.notifyServiceEnabled();
		return START_STICKY;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();

		try {
			this.unregisterReceiver(this.mSmsReceiver);
		} catch (Exception e) {
		}
		try {
			this.unregisterReceiver(this.mCallReceiver);
		} catch (Exception e) {
		}

		try {
			demoRunHandler.removeCallbacks(demoRunTask);
		} catch (Exception e) {
		}
		try {
			statsUpdateHandler.removeCallbacks(statusUpdater);
		} catch (Exception e) {
		}

		try {
			wakeupHandler.removeCallbacks(wakeUp);
		} catch (Exception e) {
		}

		try {
			appNotifications.notifyServiceState();
		} catch (Exception e) {
		}
	}

	public final void postPhoneAttrbutes() {

		mAppConfig.rePopulate();

		if (!mAppConfig.isConnectedToNetwork())
			return;

		if (!mAppConfig.isBatteryFlag() && !mAppConfig.isSignalFlag()
				&& !mAppConfig.isLocationFlag() && !mAppConfig.isCountersFlag())
			return;

		UrlData urlData = new UrlData(mAppConfig.getDataPostUrl());

		Hashtable<String, String> htParams = mAppConfig.getDataPostHashtable();
		htParams.put(ConfigParams.mode.toString(), ConfigParams.modes.stats.toString());
		
		if (mAppConfig.isBatteryFlag())
			htParams.put(PhoneParams.batterystatus.toString(),
					mAppConfig.getBatteryStatus());

		if (mAppConfig.isSignalFlag())
			htParams.put(PhoneParams.signalstatus.toString(),
					mAppConfig.getSignalStrength());

		if (mAppConfig.isLocationFlag())
			htParams.put(PhoneParams.devicelocation.toString(),
					mAppConfig.getLocation());

		if (mAppConfig.isCountersFlag()) {
			htParams.put(PhoneParams.smssuccesscount.toString(),
					String.valueOf(mAppConfig.getSmsSuccessCount()));
			htParams.put(PhoneParams.smsinvalidcount.toString(),
					String.valueOf(mAppConfig.getSmsInvalidCount()));
			htParams.put(PhoneParams.smsdroppedcount.toString(),
					String.valueOf(mAppConfig.getSmsDroppedCount()));
			htParams.put(PhoneParams.smsfailedcount.toString(),
					String.valueOf(mAppConfig.getSmsFailedCount()));

			htParams.put(PhoneParams.callsuccesscount.toString(),
					String.valueOf(mAppConfig.getCallSuccessCount()));
			htParams.put(PhoneParams.callfailedcount.toString(),
					String.valueOf(mAppConfig.getCallFailedCount()));

		}
		urlData.postData(htParams);
	}

	private Runnable demoRunTask = new Runnable() {
		@Override
		public void run() {
			mAppConfig.rePopulate();

			ServiceStartStatus status = mAppConfig.allGoodToRunService();

			if (status == ServiceStartStatus.SubscriptionExpired
					|| status == ServiceStartStatus.DemoLimitation) {
				stopSelf();
				mAppConfig.handleServiceResponse(status);
				return;
			}
			
			demoRunHandler.postDelayed(this, TimeOuts.FiveSec.getValue());
		}
	};

	private Runnable statusUpdater = new Runnable() {

		@Override
		public void run() {
			postPhoneAttrbutes();
			statsUpdateHandler.postDelayed(this, TimeOuts.ThirtySec.getValue());
		}
	};
	
	private Runnable configPullTask = new Runnable() {
		
		@Override
		public void run() {
			mAppConfig.updateConfigFromHost();
			configPullHandler.postDelayed(this, TimeOuts.SixHr.getValue());
		}
	};
	
	private Runnable wakeUp = new Runnable() {
		
		@Override
		public void run() {
			mAppConfig.wakeUp(2000);
			wakeupHandler.postDelayed(this, 900000);
			
		}
	};
}
